package com.sidneysimmons.financially.activities;

import android.os.Bundle;
import android.support.v4.view.ViewPager;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;

import com.sidneysimmons.financially.Account;
import com.sidneysimmons.financially.Category;
import com.sidneysimmons.financially.R;
import com.sidneysimmons.financially.Validator;
import com.sidneysimmons.financially.adapters.AccountPagerAdapter;
import com.sidneysimmons.financially.adapters.DatabaseAdapter;
import com.sidneysimmons.financially.fragments.AccountFragment;
import com.sidneysimmons.financially.fragments.EditAccountDialogFragment;
import com.sidneysimmons.financially.fragments.EditCategoryDialogFragment;
import com.sidneysimmons.financially.fragments.NewAccountDialogFragment;
import com.sidneysimmons.financially.fragments.NewCategoryDialogFragment;
import com.sidneysimmons.financially.managers.AccountManager;
import com.sidneysimmons.financially.managers.CategoryManager;
import com.sidneysimmons.financially.managers.UserManager;

public class AccountActivity extends BaseActivity {
	
	private final String CLASS_NAME = this.getClass().getName();
	
	private AccountPagerAdapter pagerAdapter;
	private ViewPager viewPager;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState, CLASS_NAME);
		setContentView(R.layout.account_scroller);
		
		// Set the adapter so the Account Scroller can connect to the Account Fragments
		pagerAdapter = new AccountPagerAdapter(getSupportFragmentManager(), this);
        viewPager = (ViewPager) findViewById(R.id.account_scroller);
        viewPager.setAdapter(pagerAdapter);
	}
	
	@Override
	protected void onStart() {
		super.onStart(CLASS_NAME);
	}
	
	@Override
	protected void onResume() {
		super.onResume(CLASS_NAME);
	}
	
	@Override
	protected void onPause() {
		super.onPause(CLASS_NAME);
	}
	
	@Override
	protected void onStop() {
		super.onStop(CLASS_NAME);
	}
	
	@Override
	protected void onDestroy() {
		super.onDestroy(CLASS_NAME);
	}
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.financially, menu);
		return true;
	}
	
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		if (item.getItemId() == R.id.menu_action_log_out) {
			// Log the user out and close the app
			UserManager userManager = new UserManager(this);
			userManager.removeCurrentUser();
			finish();
		} else if (item.getItemId() == R.id.menu_action_add_new_account) {
			// Show the new account dialog
			showNewAccountDialog();
		} else if (item.getItemId() == R.id.menu_action_clear_tables) {
			// Erase the database tables
			DatabaseAdapter database = new DatabaseAdapter(getBaseContext());
			database.eraseData();
			pagerAdapter.notifyDataSetChanged();
		}
		
		return super.onOptionsItemSelected(item);
	}
	
	/**
	 * Validates the newly created Account.  If validation passes, add the new 
	 * Account via the AccountManager.  Otherwise, shows error message and re-shows 
	 * the dialog.
	 * 
	 * @param account - The Account object to validate/add
	 */
	public void validateAndCreateNewAccount(Account account) {
		// Validate the account
		boolean accountNamePassed = Validator.validateAccountName(account.getTitle());
		
		if (!accountNamePassed) {
			String errorText = getResources().getString(R.string.account_activity_text_invalid_account_name);
			Toast.makeText(getBaseContext(), errorText, Toast.LENGTH_LONG).show();
			showNewAccountDialog();
		} else {
			// Validation passed, so add via AccountManager
			AccountManager accountManager = new AccountManager(getBaseContext());
			if (accountManager.addNewAccount(account)) {
				pagerAdapter.notifyDataSetChanged();
				viewPager.setCurrentItem(pagerAdapter.getCount() - 1);
			} else {
				// Account not added, show the dialog again
				showNewAccountDialog();
			}
		}
	}
	
	/**
	 * Validates the edited Account.  If validation passes, edit the 
	 * Account via the AccountManager.  Otherwise, shows error message and re-shows 
	 * the dialog.
	 * 
	 * @param originalAccount
	 * @param updatedAccount
	 */
	public void validateAndEditAccount(Account originalAccount, Account updatedAccount) {
		// First, validate the updated account
		boolean accountNamePassed = Validator.validateAccountName(updatedAccount.getTitle());
		
		if (!accountNamePassed) {
			String errorText = getResources().getString(R.string.account_activity_text_invalid_account_name);
			Toast.makeText(getBaseContext(), errorText, Toast.LENGTH_LONG).show();
			showEditAccountDialog();
		} else {
			// Validation passed, so edit via the AccountManager
			AccountManager accountManager = new AccountManager(getBaseContext());
			if (accountManager.editAccount(originalAccount, updatedAccount)) {
				pagerAdapter.notifyDataSetChanged();
			} else {
				// Account not edited, show the dialog again
				showEditAccountDialog();
			}
		}
	}
	
	/**
	 * Validates the newly created Category.  If validation passes, add the new 
	 * Category via the CategoryManager.  Otherwise, shows error message and re-shows 
	 * the dialog.
	 * 
	 * @param account
	 * @param category
	 */
	public void validateAndCreateNewCategory(Account account, Category category) {
		// First, validate the category
		boolean categoryNamePassed = Validator.validateCategoryName(category.getTitle());
		
		if (!categoryNamePassed) {
			String errorText = getResources().getString(R.string.account_activity_text_invalid_category_name);
			Toast.makeText(getBaseContext(), errorText, Toast.LENGTH_LONG).show();
			showNewCategoryDialog();
		} else {
			// Validation passed, so add via CategoryManager
			CategoryManager categoryManager = new CategoryManager(getBaseContext());
			if (categoryManager.addCategory(account, category)) {
				pagerAdapter.notifyDataSetChanged();
			} else {
				// Category not added, show the dialog again
				showNewCategoryDialog();
			}
		}
	}
	
	/**
	 * Validates the edited Category.  If validation passes, edit the 
	 * Category via the CategoryManager.  Otherwise, shows error message and re-shows 
	 * the dialog.
	 * 
	 * @param account
	 * @param originalCategory
	 * @param updatedCategory
	 */
	public void validateAndEditCategory(Account account, Category originalCategory, Category updatedCategory) {
		// First, validate the updated category
		boolean categoryNamePassed = Validator.validateCategoryName(updatedCategory.getTitle());
		
		if (!categoryNamePassed) {
			String errorText = getResources().getString(R.string.account_activity_text_invalid_category_name);
			Toast.makeText(getBaseContext(), errorText, Toast.LENGTH_LONG).show();
			showEditCategoryDialog(originalCategory);
		} else {
			// Validation passed, so edit via the CategoryManager
			CategoryManager categoryManager = new CategoryManager(getBaseContext());
			if (categoryManager.editCategory(account, originalCategory, updatedCategory)) {
				pagerAdapter.notifyDataSetChanged();
			} else {
				// Category not edited, show the dialog again
				showEditCategoryDialog(originalCategory);
			}
		}
	}
	
	/**
	 * Delete this Account and child Categories from the database.
	 * 
	 * @param account
	 */
	public void deleteAccount(Account account) {
		// Delete via the AccountManager
		AccountManager accountManager = new AccountManager(getBaseContext());
		if (accountManager.deleteAccount(account)) {
			pagerAdapter.notifyDataSetChanged();
		} else {
			// Account could not be deleted, show the dialog again
			showEditAccountDialog();
		}
	}
	
	/**
	 * Delete this category from the database.
	 * 
	 * @param account
	 * @param category
	 */
	public void deleteCategory(Account account, Category category) {
		// Delete via the CategoryManager
		CategoryManager categoryManager = new CategoryManager(getBaseContext());
		if (categoryManager.deleteCategory(account, category)) {
			pagerAdapter.notifyDataSetChanged();
		} else {
			// Category could not be deleted, show the dialog again
			showEditCategoryDialog(category);
		}
	}
	
	/**
	 * Show the dialog fragment used to create a new Account.
	 */
	protected void showNewAccountDialog() {
		NewAccountDialogFragment dialogFragment = NewAccountDialogFragment.newInstance();
		dialogFragment.show(getSupportFragmentManager(), NewAccountDialogFragment.TAG);
	}
	
	/**
	 * Show the dialog fragment used to edit an Account.  Must supply an Account to fill in.
	 */
	protected void showEditAccountDialog() {
		EditAccountDialogFragment editAccountDialogFragment = EditAccountDialogFragment.newInstance();
		editAccountDialogFragment.show(getSupportFragmentManager(), EditAccountDialogFragment.TAG);
	}
	
	/**
	 * Show the dialog fragment used to create a new Category.
	 */
	protected void showNewCategoryDialog() {
		NewCategoryDialogFragment dialogFragment = NewCategoryDialogFragment.newInstance();
		dialogFragment.show(getSupportFragmentManager(), NewCategoryDialogFragment.TAG);
	}
	
	/**
	 * Show the dialog fragment used to edit a Category.  Must supply a Category to fill in.
	 */
	protected void showEditCategoryDialog(Category category) {
		EditCategoryDialogFragment editCategoryDialogFragment = EditCategoryDialogFragment.newInstance(category);
		editCategoryDialogFragment.show(getSupportFragmentManager(), EditCategoryDialogFragment.TAG);
	}
	
	/**
	 * Gets the Account that is currently being viewed.
	 * 
	 * @return Account
	 */
	public Account getAccountInFocus() {
		int current = viewPager.getCurrentItem();
		AccountFragment fragment = (AccountFragment) pagerAdapter.getItem(current);
		return fragment.getAccount();
	}
}